package com.cn.demo.aop;

import com.cn.demo.annotation.GuavaRateLimiter;
import com.cn.demo.annotation.RedisRateLimiter;
import com.cn.demo.util.R;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.RedissonRateLimiter;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 描述
 *
 * @author wangjf
 * @version 1.0
 * @createDate 2019/11/28 15:10
 * @projectName demo
 */
@Slf4j
@Component
@Aspect
public class RedissonRateLimiterAspect {

    @Autowired
    private RedissonClient redisson;

    @Around("@annotation(com.cn.demo.annotation.RedisRateLimiter)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        String classMethodName = joinPoint.getTarget().getClass().getSimpleName()+joinPoint.getSignature().getName();
        RRateLimiter rateLimiter = redisson.getRateLimiter(classMethodName);

        log.info("拦截到了{}方法...",classMethodName );
        Object obj = null;
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();

        if (targetMethod.isAnnotationPresent(RedisRateLimiter.class)) {
            RedisRateLimiter rateLimit = targetMethod.getAnnotation(RedisRateLimiter.class);
            //rateLimiter.setRate(rateLimit.permitsPerSecond());
            if (!rateLimiter.tryAcquire(rateLimit.timeOut(), rateLimit.timeOutUnit())) {
                log.info("=====    接口并发量过大    =====");
                return R.failed("接口达到了最大并发");
            } else {
                obj = joinPoint.proceed();
            }
        }
        return obj;

    }





}
